From 6127d3550ef703b9948f4e33c53a0a94df24e46c Mon Sep 17 00:00:00 2001 From: Phil Thompson Date: Mon, 13 Jul 2026 16:01:40 +0100 Subject: [PATCH] Support for Python v3.15 The project can now be built with Python v3.15 (where the limited ABI version targeted will be v3.13). (cherry picked from commit 04c516de9e360ccea2407d5d3a72de3df161ceab) Gbp-Pq: Name Support-for-Python-v3.15.patch --- qpy/QtCore/qpycore_pyqtslot.cpp | 39 ++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/qpy/QtCore/qpycore_pyqtslot.cpp b/qpy/QtCore/qpycore_pyqtslot.cpp index 0dc4987..440a6d7 100644 --- a/qpy/QtCore/qpycore_pyqtslot.cpp +++ b/qpy/QtCore/qpycore_pyqtslot.cpp @@ -97,7 +97,9 @@ PyQtSlot::Result PyQtSlot::invoke(void **qargs, PyObject *self, void *result, else { // Use the value we have if one wasn't supplied. - if (!self) + if (self) + Py_INCREF(self); + else self = instance(); // If self is NULL then we didn't have a method in the first place. @@ -108,12 +110,18 @@ PyQtSlot::Result PyQtSlot::invoke(void **qargs, PyObject *self, void *result, // See if the instance has gone (which isn't an error). if (self == Py_None) + { + Py_DECREF(self); return PyQtSlot::Ignored; + } // If the receiver wraps a C++ object then ignore the call if it no // longer exists. if (!no_receiver_check && PyObject_TypeCheck(self, sipSimpleWrapper_Type) && !sipGetAddress((sipSimpleWrapper *)self)) + { + Py_DECREF(self); return PyQtSlot::Ignored; + } sipMethodDef callable_m; @@ -121,6 +129,7 @@ PyQtSlot::Result PyQtSlot::invoke(void **qargs, PyObject *self, void *result, callable_m.pm_self = self; callable = sipFromMethod(&callable_m); + Py_DECREF(self); } // Convert the C++ arguments to Python objects. @@ -181,7 +190,11 @@ bool PyQtSlot::operator==(PyObject *callable) const if (other) return false; - return (mfunc == callable_m.pm_function && instance() == callable_m.pm_self); + PyObject *instance_obj = instance(); + bool res = (mfunc == callable_m.pm_function && instance_obj == callable_m.pm_self); + Py_XDECREF(instance_obj); + + return res; } if (!other) @@ -202,14 +215,30 @@ bool PyQtSlot::operator==(PyObject *callable) const } -// Get the instance object. +// Get a strong reference to the instance object, otherwise return NULL or a +// strong referenc to Py_None. PyObject *PyQtSlot::instance() const { + PyObject *instance_obj; + // Use the weak reference if possible. if (mself_wr) - return PyWeakref_GetObject(mself_wr); + { +#if PY_VERSION_HEX >= 0x030f0000 + if (PyWeakref_GetRef(mself_wr, &instance_obj) < 0) + instance_obj = NULL; +#else + instance_obj = PyWeakref_GetObject(mself_wr); + Py_XINCREF(instance_obj); +#endif + } + else + { + instance_obj = mself; + Py_XINCREF(instance_obj); + } - return mself; + return instance_obj; } -- 2.30.2